package com.tudouji.project.bill.service.impl;

import com.flow.service.pojo.ResultParam;
import com.flow.service.pojo.result.FlowResult;
import com.flow.service.process.service.impl.FlowTempNodeServiceImpl;
import com.tudouji.common.enums.WhinformTypeEnums;
import com.tudouji.common.exception.CustomException;
import com.tudouji.common.utils.DateUtils;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.SecurityUtils;
import com.tudouji.common.utils.poi.ExcelTempUtil;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.project.bill.domain.*;
import com.tudouji.project.bill.mapper.SellformMapper;
import com.tudouji.project.bill.mapper.WhinformMapper;
import com.tudouji.project.bill.mapper.WhinformitemMapper;
import com.tudouji.project.bill.service.IWhinformService;
import com.tudouji.project.flow.utils.FlowProcessUtil;
import com.tudouji.project.harvest.domain.Freightorder;
import com.tudouji.project.harvest.mapper.FreightorderMapper;
import com.tudouji.project.permission.service.ISalespermissionService;
import com.tudouji.project.produce.domain.*;
import com.tudouji.project.produce.mapper.MaterialretapplyMapper;
import com.tudouji.project.produce.mapper.ProduceplanMapper;
import com.tudouji.project.produce.mapper.WhinapplyMapper;
import com.tudouji.project.produce.mapper.WhinapplyitemMapper;
import com.tudouji.project.produce.service.impl.PickinglistServiceImpl;
import com.tudouji.project.produce.service.impl.WhinapplyServiceImpl;
import com.tudouji.project.product.domain.Productinfo;
import com.tudouji.project.product.domain.Salesspecification;
import com.tudouji.project.product.mapper.ProductinfoMapper;
import com.tudouji.project.product.mapper.SalesspecificationMapper;
import com.tudouji.project.purchasebill.domain.Purchasebill;
import com.tudouji.project.purchasebill.mapper.PurchasebillMapper;
import com.tudouji.project.store.domain.Storehouseroom;
import com.tudouji.project.store.domain.Storeroom;
import com.tudouji.project.store.mapper.StorehouseroomMapper;
import com.tudouji.project.store.mapper.StoreroomMapper;
import com.tudouji.project.store.service.IStockunitService;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.mapper.SysUserMapper;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 入库单Service业务层处理
 *
 * @author wf
 * @date 2021-01-07
 */
@Slf4j
@Service
public class WhinformServiceImpl implements IWhinformService {
    @Autowired
    private WhinformMapper whinformMapper;
    @Autowired
    private FreightorderMapper freightorderMapper;
    @Autowired
    private WhinfoServiceImpl whinfoService;
    @Autowired
    private WhinformitemMapper whinformitemMapper;
    @Autowired
    private ISalespermissionService permissionService;
    @Autowired
    private BusinesscodeServiceImpl codeService;
    @Autowired
    private IWhinformService whinformService;
    @Autowired
    private StorehouseroomMapper storehouseroomMapper;
    @Autowired
    private StoreroomMapper storeroomMapper;
    @Autowired
    private WhoutformServiceImpl whoutformService;
    @Autowired
    private TransferapplyServiceImpl transferapplyService;
    @Autowired
    private TransferapplyitemServiceImpl tranitemService;
    @Autowired
    private FlowTempNodeServiceImpl nodeService;
    @Autowired
    private FlowProcessUtil processUtils;
    @Autowired
    private SalesspecificationMapper salesspecificationMapper;
    @Autowired
    private ProductinfoMapper productinfoMapper;

    @Autowired
    private WhinapplyServiceImpl whinapplyService;
    @Autowired
    private WhinapplyMapper whinapplyMapper;
    @Autowired
    private MaterialretapplyMapper materialretapplyMapper;
    @Autowired
    private SellformMapper sellformMapper;
    @Autowired
    private PurchasebillMapper purchasebillMapper;

    @Autowired
    private IStockunitService stockunitService;
    @Autowired
    private PickinglistServiceImpl pickinglistService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private WhoutformServiceImpl outService;

    @Autowired
    private ProduceplanMapper produceplanMapper;

    @Autowired
    private SalesspecificationMapper speService;

    @Autowired
    private WhinfoServiceImpl infoService;

    @Autowired
    private WhinapplyitemMapper whinapplyitemMapper;
    @Autowired
    private ExcelTempUtil excelTempUtil;

    /**
     * 查询入库单
     *
     * @param autoid 入库单ID
     * @return 入库单
     */
    @Override
    public Whinform selectWhinformById(Long autoid) {
        return whinformMapper.selectWhinformById(autoid);
    }

    /**
     * 查询入库单列表
     *
     * @param whinform 入库单
     * @return 入库单
     */
    @Override
    public List<Whinform> selectWhinformList(Whinform whinform) {
        return whinformMapper.selectWhinformList(whinform);
    }
    @Override
    public List<Whinform> selectWhinformBaseList(Whinform whinform) {
        return whinformMapper.selectWhinformBaseList(whinform);
    }

    /**
     * 新增入库单
     *
     * @param whinform 入库单
     * @return 结果
     */
    @Override
    public int insertWhinform(Whinform whinform) {
        return whinformMapper.insertWhinform(whinform);
    }

    /**
     * 修改入库单
     *
     * @param whinform 入库单
     * @return 结果
     */
    @Override
    public int updateWhinform(Whinform whinform) {
        return whinformMapper.updateWhinform(whinform);
    }

    /**
     * 批量删除入库单
     *
     * @param autoids 需要删除的入库单ID
     * @return 结果
     */
    @Override
    public int deleteWhinformByIds(Long[] autoids) {
        return whinformMapper.deleteWhinformByIds(autoids);
    }

    /**
     * 删除入库单信息
     *
     * @param autoid 入库单ID
     * @return 结果
     */
    @Override
    public int deleteWhinformById(Long autoid) {
        return whinformMapper.deleteWhinformById(autoid);
    }

    /**
     * 入库单查询
     *
     * @param whinform
     * @return
     */
    @Override
    public List<Whinform> findWhinformList(Whinform whinform) {

        return this.whinformMapper.findWhinformList(whinform);
    }

    @Override
    public List<Whinform> findFreightWhin(Whinform whinform) {

        return this.whinformMapper.findFreightWhin(whinform);
    }

    @Override
    public void whinBack(SysUser sysUser, String orderid) {
        //查询入库单
        Whinform inform = new Whinform();
        inform.setFoguid(orderid);
        List<Whinform> informs = whinformMapper.selectWhinformList(inform);
        inform = informs.get(0);

        //查询入库单明细
        Whinformitem item = new Whinformitem();
        item.setWhinid(inform.getGuid());
        List<Whinformitem> items = whinformitemMapper.selectWhinformitemList(item);

        //反向生成入库单
//        inform.setGuid("");
        inform.setCreatedate(DateUtils.getNowDate());
        inform.setGuid(IdUtils.fastSimpleUUID());

        inform.setFormno(codeService.getCode("4"));
        inform.setOperatorid(sysUser.getGuid());
        inform.setRemark("反向生成入库单！");
        inform.setQty(inform.getQty().negate());
        whinformMapper.insertWhinform(inform);

        for (Whinformitem it : items) {
//            it.setGuid("");
            it.setGuid(IdUtils.fastSimpleUUID());
            it.setWhinid(inform.getGuid());
            it.setWeight(it.getWeight().negate());
            it.setCreateTime(DateUtils.getNowDate());
            it.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whinformitemMapper.insertWhinformitem(it);

            Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(it.getShrguid());

            // 更新库存信息
            Whinfo info;
            if (house.getShrtype() == 1) {//1-原材料库，2-产成品库 3-废品库（不合格品库）
                info = whinfoService.getWhinfo(it.getOrgguid(), it.getProductguid(), it.getSrguid(),
                        it.getShrguid(), null);
            } else {
                info = whinfoService.getWhinfo(it.getOrgguid(), it.getProductguid(), it.getSrguid(),
                        it.getShrguid(), it.getSpguid());
            }
            if (info != null) {
                Whinfo upinfo = new Whinfo();
                upinfo.setGuid(info.getGuid());
                upinfo.setStoreqty(info.getStoreqty().add(it.getWeight()));
                whinfoService.updateWhinfo(upinfo);
            }
        }
    }

    @Override
    @Transactional
    public void newWhinBack(SysUser sysUser, String orderid) {
        //查询入库单
        Whinform inform = new Whinform();
        inform.setFoguid(orderid);
        List<Whinform> informs = whinformMapper.selectWhinformList(inform);
        inform = informs.get(0);

        //查询入库单明细
        Whinformitem item = new Whinformitem();
        item.setWhinid(inform.getGuid());
        List<Whinformitem> items = whinformitemMapper.selectWhinformitemList(item);

        //反向生成入库单
        inform.setRemark("反向生成入库单！");
        inform.setQty(inform.getQty().negate());

        for (Whinformitem it : items) {
            it.setWeight(it.getWeight().negate());
        }
        inform.setItems(items);
        this.whin(inform, true);
    }

    @Override
    @Transactional
    public AjaxResult saveTransferApplyWhin(String imgids, SysUser sysUser, Whinform form, List<Whinformitem> items
            , Transferapply apply, Long taskid, String opinion, boolean fromAuto) {
        log.debug("*****************TransferTask--transferWhin--savePurchasebillWhin");
        form.setFormno(codeService.getCode("4"));
        log.debug("=-=-=-savePurchasebillWhin,shrid:"+items.get(0).getShrguid());
        //20240124
//        saveWhinfo(items, form);
        for (Whinformitem item : items) {
            item.setItemguid(item.getApplyitemid());
        }
        form.setItems(items);
        whinformService.whin(form, false);
        //更新调拨申请单明细入库重量
        BigDecimal unloadweight = new BigDecimal(0);
        for (Whinformitem item : items) {
            Transferapplyitem transferitem = new Transferapplyitem();
            transferitem.setGuid(item.getApplyitemid());
            transferitem.setUnloadweight(item.getWeight());
            //获取库间名字
            Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
            if (apply.getType() == 1) {
                transferitem.setToshguid(item.getShrguid());
                transferitem.setToshname(house.getName());
            } else {
                transferitem.setFromshguid(item.getShrguid());
                transferitem.setFromshname(house.getName());
            }
            unloadweight = whoutformService.calculateWeight(item.getSpguid() == null ? item.getRawspguid() : item.getSpguid(), item.getWeight(), null, 3).get("toT");
            tranitemService.updateTransferapplyitem(transferitem);

        }
        apply.setUnloadweight(unloadweight);
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(apply.getFromsrguid());
        apply.setPlatformId(Long.valueOf(storeroom.getId()));
        if (apply.getTosrguid() != null) {
            Storeroom storeroomTo = storeroomMapper.selectStoreroomByGuid(apply.getTosrguid());
            apply.setToPlatformId(Long.valueOf(storeroomTo.getId()));
        }


        if (fromAuto) {
            FlowResult result = processUtils.defaultApproval(taskid, imgids, opinion, apply
                    , sysUser);
            if (result.getMsg().equals(ResultParam.SUCCESS)) {
                Transferapply pb = new Transferapply();
                pb.setStatus(result.getNextStat());
                pb.setGuid(apply.getGuid());
                transferapplyService.updateTransferapply(pb);
                return AjaxResult.success();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error(result.getMsg());
            }
        }else {
            return AjaxResult.success();
        }
    }

    @Override
    public List<Whinform> findDetail(Whinform whinform) {
        return whinformMapper.findDetail(whinform);
    }

    @Override
    public List<Whinform> selectWhinformsHistory() {
        return whinformMapper.selectWhinformsHistory();
    }

    @Override
    public List<Whinform> selectWhinformDetail(Whinform in) {
        return whinformMapper.selectWhinformDetail(in);
    }

    @Transactional
    @Override
    public AjaxResult produceWhin(Whinform whinform, Long applyid, String fileIds, String opinion, Long taskid) {

        log.info("----do whin start----");
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Whinapply apply = whinapplyService.selectWhinapplyByAutoId(applyid);
        Pickinglist pick = pickinglistService.selectPickinglistById(apply.getPickinglistid());

        BigDecimal nowWeight = new BigDecimal(0);
        AjaxResult result = new AjaxResult();
        //自有生产的情况下 需要校验重量
//        if(pick.getFlag()!=2){
//            for(Whinformitem item:whinform.getItems()){
//                Storehouseroom house=storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
//                if(house.getShrtype()!=4){//辅料不参与计算
//                    nowWeight=nowWeight.add(outService.calculateWeight(item.getSpguid(), item.getWeight(), null, 3).get("toT"));
//                }
//            }
//            result=pickinglistService.checkWeight(apply.getPickinglistid(), nowWeight);
//
//            log.info("------code:::{}",result.get("code"));
//            log.info("------pickgetFlag:::{}",pick.getFlag());
//            log.info("-----result.get(\"code\").equals(\"200\")----{}",(result.get("code").equals("200")));
//            log.info("-----result.get(\"code\").equals(\"200\")----{}",((int)result.get("code")==200));
//        }
//        if((int)result.get("code")==200||pick.getFlag()==2){//自有生产重量校验通过或者 代工生产 可直接入库
        //获取计划 (需要获取计划时间)
//        Produceplan plan = produceplanMapper.selectProduceplanById(apply.getProduceplanid());

        //组装入库单
        whinform.setBusinesscode(apply.getCode());
        whinform.setFoguid(apply.getGuid());
        whinform.setDepartmentid(pick.getDepartmentid());
        extracted(apply, whinform);
        whinform.setStorermguid(apply.getSrguid());
        whinform.setCreatedate(DateUtils.getNowDate());//createtime的含义修改为业务入库日期 ,业务日期记录生产计划的开始日期
        whinform.setOperatorid(user.getGuid());
        whinform.setWhintype(4);


        result = saveProduceWhinfo(fileIds, user, whinform, apply, taskid);
        return result;//返回值success:成功,nospguid:没有规格id
//        }else{
//            return result;
//        }
    }

    @Override
    public Double getSumWeight(Whinform whinform) {
        return whinformMapper.getSumWeight(whinform);
    }

    @Override
    public AjaxResult produceWhin(Long autoid) {
        Map<String, Object> map = getwhinPrintData(autoid);

        return excelTempUtil.exportWhin(map);
    }

    @Override
    public AjaxResult printWhinHtml(Long autoid) {
        Map<String, Object> map = getwhinPrintData(autoid);

        return excelTempUtil.exportWhinHtml(map);
    }

    private Map<String, Object> getwhinPrintData(Long autoid) {
        Whinform whinform = whinformMapper.getWhinFormForPrint(autoid);
        String supplier = null;
        String customer = null;
        String submitter = null;
        Date orderDate = null;
        String deptName = null;
        BigDecimal amount = null;
        if (1 == whinform.getWhintype()) {
            Freightorder freightorder = freightorderMapper.selectFreightorderById(whinform.getFoguid());
            supplier = freightorder.getSupplierName();
//            customer = freightorder.getOrgName();
            submitter = freightorder.getOperator();
            orderDate = freightorder.getCreatetime();
            deptName = freightorder.getDepartment();
            //20240520 修改为入库单的amount
//            amount = freightorder.getSettlement();
            amount = whinform.getAmount();
        }
        if (2 == whinform.getWhintype() || 7 == whinform.getWhintype()) {
            Transferapply transferapply = transferapplyService.selectTransferapplyById(whinform.getFoguid());
//            supplier = transferapply.getOrgname();
//            customer = transferapply.getToorgname();
            submitter = transferapply.getApplyname();
            orderDate = transferapply.getCreatetime();
            deptName = transferapply.getDepartname();
        }
        if (4 == whinform.getWhintype()) {
            Whinapply whinapply = whinapplyMapper.selectWhinapplyById(whinform.getFoguid());
//            supplier = whinapply.getOrgname();
//            customer = whinapply.getOrgname();
            submitter = whinapply.getCreateName();
            orderDate = whinform.getCreatedate();
            deptName = whinapply.getDeptName();
        }
        if (6 == whinform.getWhintype()) {
            Materialretapply materialretapply = materialretapplyMapper.selectMaterialretapplyById(whinform.getFoguid());
//            supplier = materialretapply.getOrgname();
//            customer = materialretapply.getOrgname();
            submitter = materialretapply.getOperatorName();
            orderDate = materialretapply.getCreatetime();
            deptName = materialretapply.getDeptName();
        }
        if (8 == whinform.getWhintype()) {
            Sellform sellform = sellformMapper.selectSellformByGuid(whinform.getFoguid());
//            supplier = sellform.getOrgName();
            customer = sellform.getCustomername();
            submitter = sellform.getApplyname();
            orderDate = sellform.getCreatetime();
            deptName = sellform.getDepname();
        }
        if (9 == whinform.getWhintype()) {
            Purchasebill purchasebill = purchasebillMapper.selectPurchasebillByGuid(whinform.getFoguid());
            supplier = purchasebill.getSupplier();
//            customer = purchasebill.getOrgname();
            submitter = purchasebill.getOperator();
            orderDate = purchasebill.getCreatetime();
            deptName = purchasebill.getDepartment();
            amount = purchasebill.getTotalamount();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("orgName", whinform.getOrgFullName());
        map.put("typeName", whinform.getWhintypeName());
        map.put("code", whinform.getBusinesscode());//订单编号
        map.put("supplier", supplier);//供应商
        map.put("customer", customer);//客户
        map.put("whname", whinform.getStrname());//库房
        map.put("submitter", submitter);//提交人
        map.put("orderDate", orderDate);//订单日期
        map.put("whoutDate", whinform.getCreatedate());//出入库日期
        map.put("whOperator", whinform.getOperator());//库管
        map.put("deptName", deptName);//库管
        map.put("amount", amount);//库管
        List<Whinformitem> items = whinform.getItems();
        if (items.size() > 0){
            for (int i = 0; i < items.size(); i++) {
                Whinformitem whinformitem = items.get(i);
                if (null != whinformitem.getPrice()){
                    String strNumber = whinformitem.getPrice().toString();
                    if (strNumber.contains(".")){
                        String trimmedNumber = strNumber.replaceAll("0*$", "");
                        BigDecimal price = new BigDecimal(trimmedNumber);
                        whinformitem.setPrice(price);
                    }
                }
            }
        }
        map.put("list", items);
        return map;
    }

    public AjaxResult saveProduceWhinfo(String fileIds, SysUser user, Whinform form, Whinapply apply, Long taskId) {
        form.setFormno(codeService.getCode("4"));
        //20240123 修改采购入库逻辑
//        String msg = saveWhinfo(form);
        whinformService.whin(form, false);

//        log.info("---mesg:{}", msg);
//        if (msg.equals("success")) {
            //更新入库申请单明细中的库间id
            for (Whinformitem item : form.getItems()) {
                Whinapplyitem i = new Whinapplyitem();
                i.setGuid(item.getApplyitemid());
                i.setSpecguid(item.getSpguid());
                i.setSpename(item.getSpename());
                i.setShguid(item.getShrguid());
                i.setWeight(item.getWeight());
                whinapplyitemMapper.updateWhinapplyitem(i);
            }
            log.info("---------taskId:{}", taskId);
//            apply.setPlatformId(apply.getStrmId());
            FlowResult result = processUtils.defaultApproval(taskId, fileIds, "生产入库", apply
                    , user);
            if (result.getMsg().equals(ResultParam.SUCCESS)) {
                Whinapply pb = new Whinapply();
                pb.setStatus(result.getNextStat());
                pb.setGuid(apply.getGuid());
                whinapplyService.updateWhinapply(pb);
                return AjaxResult.success();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                log.info("----result:{}", result.getMsg());
                return AjaxResult.error(result.getMsg());
            }
//        }
//        log.info("-----end error---");
//        return AjaxResult.error(msg);
    }

    /**
     * 生产入库信息保存
     *
     * @param form
     * @throws Exception
     */
    public String saveWhinfo(Whinform form) {
        if (form.getItems().size() == 0) {
            throw new CustomException("明细为空！");
        }
        String guid = IdUtils.fastSimpleUUID();
        form.setGuid(guid);
        whinformMapper.insertWhinform(form);
        //完善入库明细
        BigDecimal weight = new BigDecimal(0);
        for (Whinformitem item : form.getItems()) {
            String itemGuid = IdUtils.fastSimpleUUID();
            item.setGuid(itemGuid);
            item.setWhinid(guid);
            item.setSrguid(form.getStorermguid());
            item.setOrgguid(form.getOrgguid());
            item.setOrgname(form.getOrgname());

            if (StringUtils.isNotBlank(item.getSpguid())) {
                Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
                if (1 == house.getShrtype()) {
                    //原材料  写入统一规格
                    Salesspecification spe = new Salesspecification();
                    spe.setProductguid(item.getProductguid());
                    spe.setBaseFlag(1);
                    spe = speService.selectSalesspecificationList(spe).get(0);

                    item.setSpename(spe.getName());
                    item.setSpguid(spe.getGuid());
                }
            } else {
                throw new CustomException("明细规格有误！");
            }
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whinformitemMapper.insertWhinformitem(item);

            weight = weight.add(item.getWeight());
            // 更新库存信息
            Whinfo info = new Whinfo();
            if (form.getWhintype() == 8) {
                info = infoService.getFarmerWhinfo(item.getProductguid(), item.getSrguid(),
                        item.getShrguid());
            } else {
                if (StringUtils.isNotBlank(item.getSpguid())) {
                    info = infoService.getWhinfo(form.getOrgguid(), item.getProductguid(), item.getSrguid(),
                            item.getShrguid(), item.getSpguid());
                } else {
                    //回滚
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    //没有规格id
//                    return "nospguid";
                    throw new CustomException("库存不足！");
                }
            }

            if (info != null) {
                //2023.09.15如果是库存为负数，入库时单价直接写入当前订单单价
                if (info.getStoreqty().compareTo(BigDecimal.ZERO) <= 0){
                    info.setPrice(form.getPrice());
                }else{
                    //采收入库的时候计算加权平均价格
                    if (form.getWhintype() == 1) {
                        if (info.getPrice() == null){
                            info.setPrice(form.getPrice());
                        }else{
                            info.setPrice(((info.getStoreqty().multiply(info.getPrice() == null ? BigDecimal.ZERO : info.getPrice()).add(form.getQty().multiply(form.getPrice())))
                                    .divide((info.getStoreqty().add(form.getQty())), 6, BigDecimal.ROUND_DOWN)));
                        }
                    }
                }
                info.setStoreqty(info.getStoreqty().add(item.getWeight()));
                infoService.updateWhinfo(info);
            } else {
                Whinfo whinfo = new Whinfo();
                String whinfoGuid = IdUtils.fastSimpleUUID();
                whinfo.setGuid(whinfoGuid);
                whinfo.setStorermguid(item.getSrguid());
                whinfo.setStorehguid(item.getShrguid());
                whinfo.setProductid(item.getProductguid());
                whinfo.setSpguid(item.getSpguid());
                whinfo.setStoreqty(item.getWeight());
                whinfo.setCreatedate(new Date());
                whinfo.setOperatorid(form.getOperatorid());
                whinfo.setOrgguid(form.getOrgguid());
                whinfo.setStockunit(item.getStockunit());
                whinfo.setStockunitid(item.getStockunitid());
                //采收入库的时候写入单价
                if (form.getWhintype() == 1) {
                    whinfo.setPrice(form.getPrice());
                }
                //获取产品名称
                Productinfo product = productinfoMapper.selectProductinfoById(item.getProductguid());
                whinfo.setProductname(product.getProductname());
                infoService.insertWhinfo(whinfo);
            }
        }
        //更新入库单 重量
        Whinform wf = new Whinform();
        if (form.getWhintype() == 8) {
            wf.setWhintype(7);
        }
//        wf.setGuid(guid);
        wf.setAutoid(form.getAutoid());
        log.info("=-=-=-=-autoid:"+form.getAutoid());
        wf.setQty(weight);

        whinformMapper.updateWhinform(wf);
        return "success";
    }

    /**
     * 生产入库信息保存
     * back=true，反入库
     * @param form
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void whin(Whinform form, boolean back) {
        if (form.getItems().size() == 0) {
            throw new CustomException("明细为空！");
        }

        //20240806 批量不能通过SecurityUtils获取user，需要批量业务提前设置好Operatorid
        SysUser user ;

        if(form.getOperatorid()==null){
            user = SecurityUtils.getLoginUser().getUser();
        }else{
            user = sysUserMapper.selectUserByGuid(form.getOperatorid());
        }

        String guid = IdUtils.fastSimpleUUID();
        form.setGuid(guid);

        form.setOperatorid(user.getGuid());
        form.setCreatedate(new Date());
        form.setFormno(codeService.getCode("4"));

        whinformMapper.insertWhinform(form);
        //完善入库明细
        BigDecimal weight = new BigDecimal(0);
        BigDecimal totalAmount = new BigDecimal(0);
        for (Whinformitem item : form.getItems()) {
            String itemGuid = IdUtils.fastSimpleUUID();
            item.setGuid(itemGuid);
            item.setWhinid(guid);
            item.setSrguid(form.getStorermguid());
            item.setOrgguid(form.getOrgguid());
            item.setOrgname(form.getOrgname());

            itemValidate(form,item);

            //入库数量以及单价转换为库存单位数量、库存数量单价
            Salesspecification salesspecification =  salesspecificationMapper.selectSalesspecificationById(item.getSpguid());
            if (!back){
                processWhinWeightAndPrice(form,item,salesspecification);
            }

            item.setStockunitid(salesspecification.getStockunitid());
            item.setStockunit(salesspecification.getStockunit());

            if (item.getPrice() != null){
                item.setAmount(item.getPrice().multiply(item.getWeight()));
                totalAmount = totalAmount.add(item.getAmount());
            }

            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(user.getUserId());

            whinformitemMapper.insertWhinformitem(item);

            weight = weight.add(item.getWeight());
            // 更新库存信息
            Whinfo info = infoService.getWhinfo(form.getOrgguid(), item.getProductguid(), item.getSrguid(),
                        item.getShrguid(), item.getSpguid());

            if (info != null) {
                //入库的时候计算加权平均价格
                calculateWhinfoPrice(info,form,item);

                info.setStoreqty(info.getStoreqty().add(item.getWeight()));
                infoService.updateWhinfo(info);
            } else {
                Whinfo whinfo = new Whinfo();
                String whinfoGuid = IdUtils.fastSimpleUUID();
                whinfo.setGuid(whinfoGuid);
                whinfo.setStorermguid(item.getSrguid());
                whinfo.setStorehguid(item.getShrguid());
                whinfo.setProductid(item.getProductguid());
                whinfo.setSpguid(item.getSpguid());
                whinfo.setStoreqty(item.getWeight());
                whinfo.setCreatedate(new Date());
                whinfo.setOperatorid(form.getOperatorid());
                whinfo.setOrgguid(form.getOrgguid());
                whinfo.setStockunit(item.getStockunit());
                whinfo.setStockunitid(item.getStockunitid());
                //入库的时候计算加权平均价格
                calculateWhinfoPrice(whinfo,form,item);

                //获取产品名称
                Productinfo product = productinfoMapper.selectProductinfoById(item.getProductguid());
                whinfo.setProductname(product.getProductname());
                infoService.insertWhinfo(whinfo);
            }
        }
        //更新入库单 重量
        Whinform wf = new Whinform();
        if (form.getWhintype() == 8) {
            wf.setWhintype(7);
        }
//        wf.setGuid(guid);
        wf.setAutoid(form.getAutoid());
        log.info("=-=-=-=-autoid:"+form.getAutoid());
        wf.setQty(weight);
        //20240123 入库单金额字段
        wf.setAmount(totalAmount);

        whinformMapper.updateWhinform(wf);
    }
    /**
     * 入库时计算库存成本价，当前算法：加权平均价
     * @param info    库存数据
     * @param item    入库单明细数据
     */
    private void calculateWhinfoPrice(Whinfo info,Whinform whinform, Whinformitem item) {
        if (item.getPrice() == null) {
            return;
        }
        //如果库存为负数，入库时单价直接写入当前订单单价
        if (info.getStoreqty().compareTo(BigDecimal.ZERO) <= 0) {
            info.setPrice(item.getPrice());
            return;
        }
        if (info.getPrice() == null) {
            info.setPrice(item.getPrice());
            return;
        }
        if (info.getStoreqty().add(item.getWeight()).compareTo(BigDecimal.ZERO) == 0) {
            return;
        }
        info.setPrice(((info.getStoreqty().multiply(
                        info.getPrice() == null ? BigDecimal.ZERO : info.getPrice()).
                add(item.getWeight().multiply(item.getPrice())))
                .divide((info.getStoreqty().add(item.getWeight())), 6, BigDecimal.ROUND_DOWN)));
    }

    /**
     * 出库出库单明细表中的出库数量
     * @param whinform    出库单主表信息
     * @param item         出库单明细表数据
     * @param spec         出库单明细表对应的物料信息
     */
    private void processWhinWeightAndPrice(Whinform whinform, Whinformitem item, Salesspecification spec) {
        if(item.getBusinessUnitId() == null){
            //如果没有传入业务单据的单位，默认为库存单位，不转换
            item.setBusinessUnitId(spec.getStockunitid());
            item.setBusinessUnitName(spec.getStockunit());
            item.setBusiunitTostockunitRate(BigDecimal.ONE);
            return;
        }
        if (item.getWeight() == null || BigDecimal.ZERO.compareTo(item.getWeight()) == 0){
            throw new CustomException(spec.getName() + "入库数量不能为0！");
        }
        BigDecimal rate = item.getBusiunitTostockunitRate();
        if(rate == null){
            //业务单据没有转换率，默认调用stockunitService.getRate将业务单位数量转换到库存单位数量
            rate = stockunitService.getRate(item.getBusinessUnitId(),spec.getStockunitid());
        }

        if(rate == null){
            throw new CustomException(spec.getName()+"库存单位转换异常！");
        }
        //入库数量转换为库存单位数量
        item.setWeight(item.getWeight().multiply(rate));
        item.setBusiunitTostockunitRate(rate);
        if (item.getPrice() != null){
            item.setPrice(item.getPrice().divide(rate, 6, BigDecimal.ROUND_HALF_UP));
        }
    }

    /**
     * 入库明细表的数据校验
     * @param item
     */
    private void itemValidate(Whinform whinform,Whinformitem item) {
        if (StringUtils.isBlank(item.getSpguid())) {
            throw new CustomException("入库明细规格有误！");
        }
        if (StringUtils.isBlank(item.getProductguid())) {
            throw new CustomException(item.getSpename()+"明细产品信息有误！");
        }
        if (StringUtils.isBlank(item.getOrgguid())) {
            throw new CustomException(item.getSpename()+"明细组织信息有误！");
        }
        if (StringUtils.isBlank(item.getSrguid())) {
            throw new CustomException(item.getSpename()+"明细库房信息有误！");
        }
        if (StringUtils.isBlank(item.getShrguid())) {
            throw new CustomException(item.getSpename()+"明细库间信息有误！");
        }
        if (item.getWeight()==null || item.getWeight().compareTo(BigDecimal.ZERO)==0) {
            throw new CustomException(item.getSpename()+"明细入库重量不能为0！");
        }
        if((whinform.getWhintype()==WhinformTypeEnums.HARVEST.getCode()||
           whinform.getWhintype()==WhinformTypeEnums.PURCHASING.getCode())
              && item.getPrice()==null){
            throw new CustomException(item.getSpename()+"价格不能为空！");
        }

    }

    private void extracted(Whinapply apply, Whinform form) {
        Storeroom room = storeroomMapper.selectStoreroomByGuid(apply.getSrguid());
        form.setOrgguid(room.getOrgguid());
        form.setOrgname(room.getOrgname());
    }

    /**
     * 生产入库信息保存
     *
     * @param form
     * @throws Exception
     */
    public String saveWhinfo(List<Whinformitem> items, Whinform form) {
//        log.debug("*****************TransferTask--transferWhin--savePurchasebillWhin--saveWhinfo");
        String guid = IdUtils.fastSimpleUUID();
        form.setGuid(guid);
        form.setCreatedate(DateUtils.getNowDate());
        whinformMapper.insertWhinform(form);
        //完善入库明细
        BigDecimal weight = new BigDecimal(0);
        for (Whinformitem item : items) {
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setWhinid(guid);
            item.setSrguid(form.getStorermguid());
            item.setOrgguid(form.getOrgguid());
            item.setOrgname(form.getOrgname());
            if (StringUtils.isBlank(item.getShrguid())){
                throw new CustomException("库间有误！");
            }
            //20230904 item.spguid为空、入库库间是原料库的情况下，获取基础原料
//            if (StringUtils.isNotBlank(item.getSpguid())) {
            if (StringUtils.isBlank(item.getSpguid())) {
                Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
                if (1 == house.getShrtype()) {
                    //原材料  写入统一规格
                    Salesspecification spe = new Salesspecification();
                    spe.setProductguid(item.getProductguid());
                    spe.setBaseFlag(1);
                    spe = salesspecificationMapper.selectSalesspecificationList(spe).get(0);

                    item.setSpename(spe.getName());
                    item.setSpguid(spe.getGuid());
                }
            }
//            log.debug(" =-=-=-=-:TransferTask b4 write into whinfoitem,shrid:"+item.getShrguid());
            item.setItemguid(item.getApplyitemid());
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whinformitemMapper.insertWhinformitem(item);

            weight = weight.add(item.getWeight());
            // 更新库存信息
            Whinfo info;
            if (form.getWhintype() == 8) {
                info = whinfoService.getFarmerWhinfo(item.getProductguid(), item.getSrguid(),
                        item.getShrguid());
            } else {
//            	if(house.getShrtype()!=1){//1-原材料库，2-产成品库 3-废品库（不合格品库） 4-辅料
                if (StringUtils.isNotBlank(item.getSpguid())) {
                    info = whinfoService.getWhinfo(form.getOrgguid(), item.getProductguid(), item.getSrguid(),
                            item.getShrguid(), item.getSpguid());
                } else {
                    //回滚
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "nospguid";//没有规格id
                    throw new CustomException("明细规格有误！");
                }
            }

            log.debug("*****************库存：" + info);
            log.debug("*****************item.getPrice：" + item.getPrice());
            if (info != null) {
                //调拨入库的时候计算加权平均价格
                if (item.getPrice() != null) {
//                    info.setPrice(((info.getStoreqty().multiply(info.getPrice() == null ? BigDecimal.ZERO : info.getPrice()).add(form.getQty().multiply(form.getPrice())))
//                            .divide((info.getStoreqty().add(form.getQty())), 2, BigDecimal.ROUND_DOWN)));
                    if (info.getPrice() == null){
                        info.setPrice(item.getPrice());
                    }else{
                        info.setPrice(((info.getStoreqty().multiply(info.getPrice() == null ? BigDecimal.ZERO : info.getPrice()).add(item.getWeight().multiply(item.getPrice())))
                                .divide((info.getStoreqty().add(item.getWeight())), 6, BigDecimal.ROUND_DOWN)));
                    }
                }
                info.setStoreqty(info.getStoreqty().add(item.getWeight()));
                whinfoService.updateWhinfo(info);
            } else {
                Whinfo whinfo = new Whinfo();
                whinfo.setGuid(IdUtils.fastSimpleUUID());
                whinfo.setStorermguid(item.getSrguid());
                whinfo.setStorehguid(item.getShrguid());
                whinfo.setProductid(item.getProductguid());
                whinfo.setSpguid(item.getSpguid());
                whinfo.setStoreqty(item.getWeight());
                whinfo.setCreatedate(new Date());
                whinfo.setOperatorid(form.getOperatorid());
                whinfo.setOrgguid(form.getOrgguid());
                whinfo.setStockunit(item.getStockunit());
                whinfo.setStockunitid(item.getStockunitid());
                //采收入库的时候写入单价
//                if (form.getWhintype() == 2) {
                    whinfo.setPrice(item.getPrice());
//                }
                //获取产品名称
                Productinfo product = productinfoMapper.selectProductinfoById(item.getProductguid());
                whinfo.setProductname(product.getProductname());
                whinfoService.insertWhinfo(whinfo);
            }
        }
        //更新入库单 重量
        Whinform wf = new Whinform();
        if (form.getWhintype() == 8) {
            wf.setWhintype(7);
        }
        wf.setAutoid(form.getAutoid());
        wf.setQty(weight);
        whinformMapper.updateWhinform(wf);
        return guid;
    }
}
